package com.example.java_gobang.api;
import com.example.java_gobang.dao.UserMapper;
import com.example.java_gobang.game.*;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

@Component
public class GameAPI extends TextWebSocketHandler {
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    RoomManager roomManager;
    @Autowired
    OnlineUserManager onlineUserManager;
    @Resource
    UserMapper userMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        GameReadyResponse response = new GameReadyResponse();
        //1 判断用户是否登录
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            response.setOk(false);
            response.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        Room room = roomManager.getRoomByUserId(user.getUserId());
        //2 用户是否已匹配成功
        if(room == null){
            response.setOk(false);
            response.setReason("用户未匹配");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }

        //3 用户是否多开
        if(onlineUserManager.getSessionByHall(user.getUserId()) != null
        || onlineUserManager.getSessionByRoom(user.getUserId()) != null){
            response.setOk(true);
            response.setReason("当前用户已登录");
            response.setMessage("repeatConnection");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        onlineUserManager.enterGameRoom(user.getUserId(), session);

        synchronized (room){
            if(room.getUser1() == null){
                room.setUser1(user);
                room.setWhiteUserId(user.getUserId());
                System.out.println("玩家1" + user.getUsername() + "已准备就绪");
                return;
            }
        }
        if(room.getUser2() == null){
            room.setUser2(user);
            System.out.println("玩家2" + user.getUsername() + "已准备就绪");
            noticeGameReady(room, room.getUser1().getUserId(), room.getUser2().getUserId());
            noticeGameReady(room, room.getUser2().getUserId(), room.getUser1().getUserId());
            return;
        }

        //房间已满
        response.setOk(false);
        response.setReason("房间已满");
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    private void noticeGameReady(Room room, int thisUserId, int thatUserId) throws IOException {
        GameReadyResponse response = new GameReadyResponse();
        response.setRoomId(room.getRoomId());
        response.setMessage("gameReady");
        response.setOk(true);
        response.setThisUserId(thisUserId);
        response.setThatUserId(thatUserId);
        response.setWhiteUserId(room.getWhiteUserId());
        WebSocketSession session = onlineUserManager.getSessionByRoom(thisUserId);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }


    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            System.out.println("用户未登录");
            return;
        }
        Room room = roomManager.getRoomByUserId(user.getUserId());
        room.putChess(message.getPayload());
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            return;
        }
        WebSocketSession existsSession = onlineUserManager.getSessionByRoom(user.getUserId());
        if(existsSession != session){
            System.out.println("当前会话不是玩家游戏的会话 不做任何处理");
            return;
        }
        System.out.println("玩家" + user.getUsername() + "出现异常下线");
        //通知对手获胜
        noticeThatUserWin(user);
        onlineUserManager.exitGameRoom(user.getUserId());


    }

    private void noticeThatUserWin(User user) throws IOException {
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room == null){
            System.out.println("房间销毁 不做处理");
            return;
        }
        User thatUser = room.getUser1() == user ? room.getUser2() : room.getUser1();
        User loseUser = room.getUser1() == thatUser ? room.getUser2() : room.getUser1();
        WebSocketSession session = onlineUserManager.getSessionByRoom(thatUser.getUserId());
        if(session == null){
            System.out.println("hhhh");
            return;
        }
        GameResponse response = new GameResponse();

        response.setMessage("putChess");
        response.setUserId(thatUser.getUserId());
        response.setWinner(thatUser.getUserId());
        response.setRow(0);
        response.setCol(0);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        userMapper.updateWin(thatUser.getUserId());
        userMapper.updateLose(loseUser.getUserId());
        roomManager.removeRoom(room.getRoomId(), thatUser.getUserId(), loseUser.getUserId());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            return;
        }
        WebSocketSession existsSession = onlineUserManager.getSessionByRoom(user.getUserId());
        if(existsSession != session){
            System.out.println("当前会话不是玩家游戏的会话 不做任何处理");
            return;
        }
        System.out.println("玩家" + user.getUsername() + "下线");
        noticeThatUserWin(user);
        onlineUserManager.exitGameRoom(user.getUserId());

    }
}
